package com.neu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neu.base.PageBean;
import com.neu.base.Result;
import com.neu.base.ServerSentEventsResult;
import com.neu.enums.ServerSentEventsEnum;
import com.neu.entity.*;
import com.neu.entity.DTO.InviteProjectUser;
import com.neu.entity.DTO.ProjectDTO;
import com.neu.entity.DTO.RemoveUserProject;
import com.neu.entity.DTO.TaskDTO;
import com.neu.entity.security.LoginUser;
import com.neu.handler.ServerSentEventsManager;
import com.neu.mapper.ProjectMapper;
import com.neu.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements ProjectService {
    @Autowired
    ProjectUserRoleService projectUserRoleService;
    @Autowired
    RoleService roleService;
    @Autowired
    UserService userService;
    @Autowired
    TaskUserService taskUserService;
    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    NoticeService noticeService;
    @Autowired
    NoticeUserService noticeUserService;



    @Autowired
    public void setNoticeService(NoticeService noticeService) {
        this.noticeService = noticeService;
    }

    @Override
    public PageBean<Project> pagelist(Integer pageNum, Integer pageSize) {
        Page<Project> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Project::getDelFlag, "1");// 查询未删除的项目

        //根据当前登录用户的权限查询通知
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();

        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(Project::getTenantId, loginUser.getTenantId());
        }

        Page<Project> tenantPage = this.baseMapper.selectPage(page, queryWrapper);
        return new PageBean<>(tenantPage);
    }

    @Override
    public List<Project> findProjectById(List<String> list) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Project::getTenantId, list)
                .eq(Project::getDelFlag, "1");// 查询未删除的项目
        return this.list(queryWrapper);
    }

    @Override
    public ProjectDTO findUserByProjectId(String projectId) {
        //先查询项目下的所有角色
        List<ProjectUserRole> projectUserRoles = projectUserRoleService.findByProjectId(projectId);
        Set<Role> roles = roleService.getRoleIdsById(projectUserRoles.stream().map(ProjectUserRole::getRoleId).collect(Collectors.toSet()));
        for (Role role : roles) {
            List<ProjectUserRole> collect = projectUserRoles.stream().
                    filter(projectUserRole -> projectUserRole.getRoleId().equals(role.getRoleId()))
                    .collect(Collectors.toList());//过滤出当前角色下的用户
            if (!collect.isEmpty()) {
                //获取当前角色下的用户
                List<String> userIds = collect.stream().map(ProjectUserRole::getUserId).collect(Collectors.toList());
                role.setUsers(userService.listByIds(userIds));
            }
        }
        Project project = this.getById(projectId);
        ProjectDTO projectDTO = new ProjectDTO();
        BeanUtil.copyProperties(project, projectDTO);
        projectDTO.setRoles(new ArrayList<>(roles));
        return projectDTO;
    }

    @Override
    public ProjectDTO getUsersByType(TaskDTO taskDTO) {
        ProjectDTO projectDTO = findUserByProjectId(taskDTO.getProjectId());
        List<Role> roles = projectDTO.getRoles();
        Role newRole = new Role();
        if (taskDTO.getTaskType().equals("1") || taskDTO.getTaskType().equals("2")) {
            //过滤出评估师
            roles = roles.stream().filter(role -> role.getRoleCode().equals("ROLE_appraiser")).collect(Collectors.toList());
            newRole = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "ROLE_appraiser"));
        } else if (taskDTO.getTaskType().equals("3")) {
            //过滤出审核员
            roles = roles.stream().filter(role -> role.getRoleCode().equals("ROLE_auditor")).collect(Collectors.toList());
            newRole = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "ROLE_auditor"));
        }
        if (roles.isEmpty()) {
            newRole.setUsers(null);
            projectDTO.setRoles(Collections.singletonList(newRole));
            return projectDTO;
        }
        List<String> userIds = roles.get(0).getUsers().stream().map(User::getUserId).collect(Collectors.toList());
        LambdaQueryWrapper<TaskUser> taskUserWrapper = new LambdaQueryWrapper();
        taskUserWrapper.in(TaskUser::getTaskId, taskDTO.getTaskId());
        List<TaskUser> taskUsers = taskUserService.list(taskUserWrapper);
        List<String> taskUserIds = taskUsers.stream().map(TaskUser::getUserId).collect(Collectors.toList());
        //在userIds去除taskUserIds
        userIds.removeAll(taskUserIds);
        System.out.println("--------" + userIds);
        if (userIds.isEmpty()) {
            newRole.setUsers(null);
            projectDTO.setRoles(Collections.singletonList(newRole));
            return projectDTO;
        }
        List<User> users = userService.listByIds(userIds);
        newRole.setUsers(users);
        projectDTO.setRoles(Collections.singletonList(newRole));
        return projectDTO;
    }

    @Override
    public ProjectDTO findUserByProjectTask(String projectId, String taskType) {
        ProjectDTO projectDTO = findUserByProjectId(projectId);
        List<Role> roles = projectDTO.getRoles();
        Role newRole = new Role();
        if (taskType.equals("1") || taskType.equals("2")) {
            //过滤出评估师
            roles = roles.stream().filter(role -> role.getRoleCode().equals("ROLE_appraiser")).collect(Collectors.toList());
            newRole = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "ROLE_appraiser"));
        } else if (taskType.equals("3")) {
            //过滤出审核员
            roles = roles.stream().filter(role -> role.getRoleCode().equals("ROLE_auditor")).collect(Collectors.toList());
            newRole = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleCode, "ROLE_auditor"));
        }
        if (roles.isEmpty()) {
            newRole.setUsers(null);
            projectDTO.setRoles(Collections.singletonList(newRole));
            return projectDTO;
        }
        List<String> userIds = roles.get(0).getUsers().stream().map(User::getUserId).collect(Collectors.toList());
        if (userIds.isEmpty()) {
            newRole.setUsers(null);
            projectDTO.setRoles(Collections.singletonList(newRole));
            return projectDTO;
        }
        List<User> users = userService.listByIds(userIds);
        newRole.setUsers(users);
        projectDTO.setRoles(Collections.singletonList(newRole));
        return projectDTO;
    }

    @Override
    public Project updateState(String projectId, String status) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Project::getProjectId, projectId);

        Project project = new Project();
        project.setProjectStatus(status);
        project.setUpdateTime(LocalDateTime.now());

        int rows = this.projectMapper.update(project, queryWrapper);

        if (rows > 0) {
            return this.projectMapper.selectOne(queryWrapper);
        } else {
            throw new RuntimeException("更新失败，可能项目不存在");
        }
    }

    @Override
    public boolean process(List<Project> projectList) {
        // 这里可以添加数据验证逻辑
        // 例如，检查必填字段是否为空，数据格式是否正确等
        for (Project project : projectList) {
            if (project.getProjectName() == null || project.getProjectName().trim().isEmpty()) {
                return false;
            }
            if (project.getProjectId() == null || project.getProjectId().trim().isEmpty()) {
                return false;
            }
            if (project.getProjectCode() == null || project.getProjectCode().trim().isEmpty()) {
                return false;
            }
        }
        // 保存数据到数据库
        this.saveBatch(projectList);
        return true;
    }

    @Override
    public PageBean<Project> search(Map map) {
        Integer pageNum = (Integer) map.get("pageNum");
        Integer pageSize = (Integer) map.get("pageSize");

        // 获取嵌套的 search Map
        Map<String, Object> searchMap = (Map<String, Object>) map.get("search");

        // 从 search Map 中获取值
        String projectname = (String) searchMap.get("projectname");
        String status = (String) searchMap.get("status");
        List<String> createTimeList = (List<String>) searchMap.get("createTimeList");
        List<String> tenantIdList = (List<String>) searchMap.get("tenantIdList");

        //把日期字符串转换为日期对象
        LocalDateTime startTime = null;
        LocalDateTime endTime = null;
        if (createTimeList != null && createTimeList.size() == 2) {
            startTime = OffsetDateTime.parse(createTimeList.get(0), DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime();
            endTime = OffsetDateTime.parse(createTimeList.get(1), DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime();
        }
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        //根据当前登录用户的权限查询
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();
        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(Project::getTenantId, loginUser.getTenantId());
        }
        Page<Project> page = new Page<>(pageNum, pageSize);

        queryWrapper.like(StringUtils.hasText(projectname), Project::getProjectName, projectname)
                .eq(StringUtils.hasText(status), Project::getProjectStatus, status)
                .between(createTimeList != null && createTimeList.size() == 2, Project::getStartTime, startTime, endTime)
                .in(!tenantIdList.isEmpty(), Project::getTenantId, tenantIdList);

        Page<Project> userIPage = projectMapper.selectPage(page, queryWrapper);

        return new PageBean<>(userIPage);
    }

    @Override
    public List<User> findUserByTenantIdFilter(Project project) {
        List<User> allUsers = userService.findUserByTenantId(project.getTenantId());
        List<ProjectUserRole> projectUserRoles = projectUserRoleService.findByProjectId(project.getProjectId());
        Set<String> userIds = projectUserRoles.stream().map(ProjectUserRole::getUserId).collect(Collectors.toSet());
        return allUsers.stream().filter(user -> !userIds.contains(user.getUserId())).collect(Collectors.toList());

    }

    @Override
    public Result inviteUser(InviteProjectUser inviteProjectUser) {
        List<User> userList = inviteProjectUser.getUserList();
        Project project = inviteProjectUser.getProject();
        String roleId = inviteProjectUser.getRoleId();
        if (userList.isEmpty()) {
            return Result.success();
        }
        List<String> userIdsList = userList.stream().map(User::getUserId).collect(Collectors.toList());
        if (!StringUtils.hasText(project.getProjectId())) {
            //说明是新建项目
            String proId = UUID.randomUUID().toString().replace("-", "");
            project.setProjectId(proId);
            List<ProjectUserRole> projectUserRoles = new ArrayList<>();
            for (User user : userList) {
                ProjectUserRole projectUserRole = new ProjectUserRole();
                projectUserRole.setProjectId(proId);
                projectUserRole.setRoleId(roleId);
                projectUserRole.setUserId(user.getUserId());
                projectUserRoles.add(projectUserRole);
            }
            projectUserRoleService.saveBatch(projectUserRoles);
            return Result.success(proId);
        }
        List<ProjectUserRole> projectUserRoles = new ArrayList<>();
        for (User user : userList) {
            ProjectUserRole projectUserRole = new ProjectUserRole();
            projectUserRole.setProjectId(project.getProjectId());
            projectUserRole.setRoleId(roleId);
            projectUserRole.setUserId(user.getUserId());
            projectUserRoles.add(projectUserRole);
        }
        projectUserRoleService.saveBatch(projectUserRoles);

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Role role = roleService.getById(roleId);

        //更新notice表
        Notice notice = new Notice();
        notice.setNoticeId(UUID.randomUUID().toString().replace("-", ""));
        notice.setNoticeTitle("项目" + project.getProjectName() + "的邀请通知");
        notice.setNoticeType("1");
        notice.setPriority("1");
        notice.setContent(loginUser.getUsername() + "邀请您成为项目" + project.getProjectName() + "的" + role.getRoleName());
        notice.setTenantId(project.getTenantId());
        notice.setProjectId(project.getProjectId());
        notice.setRoleId(roleId);
        notice.setDelFlag("1");
        notice.setCreateTime(LocalDateTime.now());
        notice.setCreateId(loginUser.getUserId());
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateId(loginUser.getUserId());
        noticeService.save(notice);

        //更新notice_user表
        for (User user : userList) {
            NoticeUser noticeUser = new NoticeUser();
            noticeUser.setNoticeId(notice.getNoticeId());
            noticeUser.setUserId(user.getUserId());
            noticeUser.setReadFlag("0");
            noticeUser.setStarFlag("0");
            noticeUserService.save(noticeUser);
        }
        ServerSentEventsManager.send(userIdsList, new ServerSentEventsResult<>(ServerSentEventsEnum.SSE_NOTICE, notice));
        return Result.success();
    }

    @Override
    public Result removeUser(RemoveUserProject removeUserProject) {
        User user = removeUserProject.getUser();
        Project project = removeUserProject.getProject();
        Role role = removeUserProject.getRole();
        //不能移除有任务的用户
        List<TaskUser> taskUsers = taskUserService.list(new LambdaQueryWrapper<TaskUser>().eq(TaskUser::getUserId, user.getUserId()));
        if(!taskUsers.isEmpty()){
            return Result.error("用户有任务，不能移除！");
        }
        LambdaQueryWrapper<ProjectUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectUserRole::getProjectId, project.getProjectId())
                .eq(ProjectUserRole::getRoleId, role.getRoleId())
                .eq(ProjectUserRole::getUserId, user.getUserId());
        //更新notice表
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Notice notice = new Notice();
        notice.setNoticeId(UUID.randomUUID().toString().replace("-", ""));
        notice.setNoticeTitle("项目" + project.getProjectName() + "的移除通知");
        notice.setNoticeType("0");
        notice.setPriority("1");
        notice.setContent(loginUser.getUsername() + "已经将您移除项目" + project.getProjectName() + "的" + role.getRoleName() + "身份！");
        notice.setTenantId(project.getTenantId());
        notice.setProjectId(project.getProjectId());
        notice.setRoleId(role.getRoleId());
        notice.setDelFlag("1");
        notice.setCreateTime(LocalDateTime.now());
        notice.setCreateId(loginUser.getUserId());
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateId(loginUser.getUserId());
        noticeService.save(notice);

        NoticeUser noticeUser = new NoticeUser();
        noticeUser.setNoticeId(notice.getNoticeId());
        noticeUser.setUserId(user.getUserId());
        noticeUser.setReadFlag("0");
        noticeUser.setStarFlag("0");
        noticeUserService.save(noticeUser);
        ServerSentEventsManager.send(user.getUserId(), new ServerSentEventsResult<>(ServerSentEventsEnum.SSE_NOTICE, notice));

        return Result.success(projectUserRoleService.remove(queryWrapper));
    }

    @Override
    public List<Project> all() {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Project::getDelFlag, "1");// 查询未删除的用户

        //根据当前登录用户的权限查询
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();

        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(Project::getTenantId, loginUser.getTenantId());
        }
        return this.list(queryWrapper);
    }

    @Override
    public Result removeProject(ProjectDTO projectDTO) {
        String projectId = projectDTO.getProjectId();
        List<ProjectUserRole> projectUserRoles = projectUserRoleService.list(new LambdaQueryWrapper<ProjectUserRole>().eq(ProjectUserRole::getProjectId, projectId));
        if(!projectUserRoles.isEmpty()){
            return Result.error("项目下还有用户参与，不能删除！");
        }

        this.removeById(projectId);
        return Result.success();
    }

    @Override
    public Result removeProjectBatch(List<String> projectIdlist) {
        for (String proId : projectIdlist) {
            List<ProjectUserRole> projectUserRoles = projectUserRoleService.list(new LambdaQueryWrapper<ProjectUserRole>().eq(ProjectUserRole::getProjectId, proId));
            if(!projectUserRoles.isEmpty()){
                Project project = this.getOne(new LambdaQueryWrapper<Project>().eq(Project::getProjectId, proId));
                return Result.error("项目"+project.getProjectName()+"下还有用户参与，不能删除！");
            }

        }

        return Result.success(this.removeByIds(projectIdlist));
    }
}
